﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
using Celeriq.Utilities;
using System.Configuration;
using System.IO;

namespace Celeriq.WinService
{
	public partial class PersistentService : ServiceBase
	{
		#region Class Members

		private System.Timers.Timer _timer = null;
		private Celeriq.Graphing.Core.ISystemCore _core = null;

		#endregion

		#region Constructor

		public PersistentService()
		{
			InitializeComponent();
		}

		#endregion

		#region Service Events

		protected override void OnStart(string[] args)
		{
			//For Debugging...
			//System.Threading.Thread.Sleep(5000);

			var log4NetConfig = Path.Combine((new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location)).DirectoryName, "log4net.config");
			log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(log4NetConfig));
			Logger.LogDebug("Services Started Begin");

			try
			{
				#region Load the service into memory
				var configuration = Celeriq.Utilities.ConfigurationSettings.GetInstance();

				if (!Directory.Exists(configuration.DataPath))
					Directory.CreateDirectory(configuration.DataPath);

				var baseAddress = new Uri("net.tcp://localhost:1973/__celeriq_core");
				var service = new Celeriq.Graphing.Core.SystemCore(false);
				var host = new ServiceHost(service, baseAddress);

				//Initialize the service
				var myBinding = new NetTcpBinding();
				myBinding.Security.Mode = SecurityMode.Transport;

				host.AddServiceEndpoint(typeof(Celeriq.Graphing.Core.ISystemCore), myBinding, string.Empty);
				host.Open();

				//Create Core Listener
				var myEndpoint = new EndpointAddress(host.BaseAddresses.First().AbsoluteUri);
				var client = new ChannelFactory<Celeriq.Graphing.Core.ISystemCore>(myBinding, myEndpoint);
				_core = client.CreateChannel();

				Logger.LogDebug("Services Started End");
				#endregion

				_timer = new System.Timers.Timer(2000);
				_timer.Elapsed += new System.Timers.ElapsedEventHandler(InitializeServices);
				_timer.Start();

			}
			catch (Exception ex)
			{
				Logger.LogError(ex);
				throw;
			}
		}

		protected override void OnStop()
		{
			KillTimer();
			try
			{
				if (_core != null) _core.ShutDown();
			}
			catch (Exception ex)
			{
				Logger.LogError(ex.ToString());
			}

			Logger.LogDebug("Services Stopped");
		}

		protected override void OnShutdown()
		{
			base.OnShutdown();
			Logger.LogDebug("Services ShutDown");
			KillTimer();
		}

		#endregion

		#region Methods

		private void InitializeServices(object sender, System.Timers.ElapsedEventArgs e)
		{
			KillTimer();
			try
			{
				_core.RestartRepositories();
			}
			catch (Exception ex)
			{
				Logger.LogError(ex.ToString());
				throw;
			}

		}

		private void KillTimer()
		{
			//Just in case
			if (_timer != null)
			{
				_timer.Enabled = false;
				_timer = null;
			}
		}

		#endregion

	}
}